package org.vectrics.recruiter.struts.admin;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import org.apache.ecs.html.Div;
import org.apache.ecs.html.Font;
import org.vectrics.SystemException;
import org.vectrics.calendar.RecruiterCalendarHelper;
import org.vectrics.calendar.struts.CalendarTag;
import org.vectrics.calendar.struts.PersonExpirableDisplayAttributes;
import org.vectrics.common.db.ExpirableRecordObject;
import org.vectrics.common.html.Cell;
import org.vectrics.common.html.JavaScriptMethod;
import org.vectrics.common.html.Row;
import org.vectrics.common.html.Table;
import org.vectrics.common.util.DateSync;
import org.vectrics.common.util.DateUtil;
import org.vectrics.common.util.StringUtils;
import org.vectrics.hibernate.ThreadProperties;
import org.vectrics.provider.CoreServiceLocator;
import org.vectrics.recruiter.RecruitServiceLocator;
import org.vectrics.recruiter.user.Interview;
import org.vectrics.recruiter.user.InterviewCriteria;
import org.vectrics.skill.UserEvaluation;
import org.vectrics.user.Person;
import org.vectrics.user.PersonCommunication;
import org.vectrics.user.PersonCommunicationMethod;
import org.vectrics.user.PersonCommunicationMethodType;
import org.vectrics.user.PersonEncounterCriteria;
import org.w3c.dom.Element;

public class RecruiterCalendarTag extends CalendarTag {
    static final long serialVersionUID = 123213421359232343L;

    private String startDate = "current";

    private String emailBackgroundColor = "#ddffdd";

    private String phoneBackgroundColor = "#f8f8cc";

    private String interviewBackgroundColor = "#ddddff";

    private String evaluationBackgroundColor = "#ddfafa";

    public RecruiterCalendarTag() {

    }

    @Override
    protected Date getDateStart() {
        String requestAttributeDate = getRequest().getParameter("dateStart");
        Date date = null;
        if (StringUtils.isNullOrBlank(requestAttributeDate) == false) {
            date = new Date(new Long(requestAttributeDate));
        } else {
            if (startDate.equals("current")) {
                date = DateSync.getCurrentTime();
            } else {
                SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
                try {
                    date = format.parse(startDate);
                } catch (Exception ex) {
                    throw new SystemException("Exception parsing date: " + startDate);
                }
            }
        }

        log.debug("Round for time period to beginning of period");
        if (getTimeMode().equals(CalendarTag.TIME_MODE_DAY)) {
            date = DateUtil.roundToDay(date);
        } else if (getTimeMode().equals(CalendarTag.TIME_MODE_WEEK)) {
            date = DateUtil.roundToWeek(date);
        } else if (getTimeMode().equals(CalendarTag.TIME_MODE_MONTH)) {
            date = DateUtil.roundToMonth(date);
        } else
            throw new SystemException("Do not know how to handle time mode: " + getTimeMode());
        return date;
    }

    @Override
    protected Date getDateEnd() {
        Date endDate = new Date(getDateStart().getTime() + 24L * 60 * 60 * 1000);
        return endDate;
    }

    @Override
    protected List getPeople() {
        ArrayList<Person> people = new ArrayList<Person>();
        people.add(ThreadProperties.getPerson());

        // Add 2nd person to test multi-people feature
        // people.add(ThreadProperties.getPerson());
        return people;
    }

    @Override
    protected List findPersonExpirables(final Person person, final Date dateStart, final Date dateEnd) {
        PersonEncounterCriteria criteria = new PersonEncounterCriteria();
        criteria.setPerson(person);
        criteria.setStartDate(dateStart);
        criteria.setEndDate(dateEnd);
        criteria.addDomain(ThreadProperties.getDomain());
        List expirables = CoreServiceLocator.getPersonService().findPersonEncounters(criteria);
        log.info("findPersonExpirables() " + "\r\n - Person: " + person + "\r\n - dateStart: " + dateStart
                + "\r\n - dateEnd:   " + dateEnd + "\r\n - count found: " + expirables.size());
        InterviewCriteria interviewCriteria = new InterviewCriteria();
        interviewCriteria.setPerson(person);
        interviewCriteria.setStartDate(dateStart);
        interviewCriteria.setEndDate(dateEnd);
        List interviews = RecruitServiceLocator.getRecruitUserService().findInterviews(interviewCriteria, 0, 1000);
        expirables.addAll(interviews);
        return expirables;
    }

    @Override
    protected String createJScript_OnItemClick() {
        StringBuffer methodStr = new StringBuffer();

        methodStr.append("function onCalendarItemClickDisplay(detailId) { \r\n");
        methodStr.append("  log('onCalendarItemClickDisplay() called - click will "
                + "bring up edit form for encounter');\r\n");

        methodStr.append("  var node = findDetailNode(detailId);\r\n");
        methodStr.append("  log('found Detail Node');\r\n");
        methodStr.append("  var meetingType = node.getAttribute('type');\r\n");
        methodStr.append("  if (meetingType == 'Phone Call') {\r\n");
        methodStr.append("      var personCommunicationId = node.getAttribute('recordId');\r\n");
        methodStr
                .append("  	var href = '"
                        + getContextPath()
                        + "/admin/user/encounter/editPhoneCallPopup.do"
                        + "?personCommunicationId=' + personCommunicationId + '&closeWindowOnSubmit=true&refreshParentOnSubmit=true';\r\n");
        methodStr.append("  	OpenLarge(href, 1);\r\n");
        methodStr.append("  }\r\n");

        methodStr.append("}\r\n");
        return methodStr.toString();
    }

    @Override
    protected String createJScript_OnCalendarClick(final Person person) {
        JavaScriptMethod method = new JavaScriptMethod();
        method.setMethodName("onCalendarClick");
        method.addLine("   log('onCalendarClick() called');");
        /*
         * String href = this.getContextPath() +
         * "/admin/user/encounter/newEncounterPopup.do" + "?personId=" +
         * person.getId().toString(); method.addLine("  	OpenLarge(" + href +
         * ", 1);\r\n");
         */
        return method.toString();
    }

    @Override
    protected String createJScript_ShowCalendarItemDetailsMethod() {
        log.info("createJScript_ShowCalendarItemDetailsMethod() - show details of selected calendar item");
        StringBuffer methodStr = new StringBuffer();
        methodStr.append("function showCalendarItemDetails(detailId) { \r\n");
        methodStr.append("  log('showCalendarItemDetails() called');\r\n");

        methodStr.append("  var node = findDetailNode(detailId);\r\n");
        methodStr.append("  log('found Detail Node');\r\n");
        methodStr.append("  var detailDiv = document.getElementById(\"detailDiv\");\r\n");
        methodStr.append("  var meetingType = node.getAttribute('type');\r\n");
        methodStr.append("  var toPersonName = node.getAttribute('toPersonName');\r\n");
        methodStr.append("  var fromPersonName = node.getAttribute('fromPersonName');\r\n");
        methodStr.append("  var dateStart = node.getAttribute('dateStartFriendly');\r\n");
        methodStr.append("  var dateEnd = node.getAttribute('dateEndFriendly');\r\n");
        methodStr.append("  var status = node.getAttribute('statusDescription');\r\n");
        methodStr.append("  log('node type = ' + meetingType);\r\n");
        // methodStr.append("      var titleElement = document.createFontElement();\r\n");

        Table table = new Table();
        Row row = table.addRow();
        row.setDefaultCellFontClass("subFont");

        addValueRow(table, "Type", "\" + meetingType + \"");
        addValueRow(table, "Status", "\" + status + \"");
        addValueRow(table, "From", "\" + fromPersonName + \"");
        addValueRow(table, "To", "\" + toPersonName + \"");
        addValueRow(table, "Start", "\" + dateStart + \"");
        addValueRow(table, "End", "\" + dateEnd +\"");

        // Turn Pretty Print of because inserted linefeeds will create illegal
        // JavaScript string.
        table.setPrettyPrint(false);
        methodStr.append("  detailDiv.innerHTML = \"" + table.toString() + "\";\r\n");
        // methodStr.append("  log(\"" + table.toString() + "\");\r\n");

        // methodStr.append("      detailDiv.innerHTML = \"<b>Text</b>\";\r\n");
        methodStr.append("  log('done placing detail text from XML data');\r\n");

        methodStr.append("}\r\n");
        // log.info("Show Detail JavaScript: " + methodStr.toString());
        return methodStr.toString();
    }

    @Override
    protected String createJScript_DeactivateDetailDisplay() {
        log.info("createJScript_DeactivateDetailDisplay() - show details of selected calendar item");
        StringBuffer methodStr = new StringBuffer();
        methodStr.append("function deactivateDetailDisplay() { \r\n");
        methodStr.append("  log('deactivateDetailDisplay() called');\r\n");

        methodStr.append("  var detailDiv = document.getElementById(\"detailDiv\");\r\n");

        methodStr.append("  detailDiv.innerHTML = \"\";\r\n");
        // methodStr.append("  log(\"" + table.toString() + "\");\r\n");
        // methodStr.append("      detailDiv.innerHTML = \"<b>Text</b>\";\r\n");
        methodStr.append("  log('done deactivating detail display');\r\n");
        methodStr.append("}\r\n");
        return methodStr.toString();
    }

    @Override
    protected void personExpirableToXml(final ExpirableRecordObject personExpirable, final Element element,
            final Locale locale) {
        RecruiterCalendarHelper helper = new RecruiterCalendarHelper();
        helper.personExpirableToXml(personExpirable, element, locale);
    }

    /**
     * Find display attributes for encounter.
     */
    @Override
    protected void findDisplayAttributes(final Person person, final ExpirableRecordObject personExpirable,
            final PersonExpirableDisplayAttributes displayInfo) {
        if (personExpirable instanceof PersonCommunication) {
            PersonCommunication personCommunication = (PersonCommunication) personExpirable;
            PersonCommunicationMethod method = personCommunication.getMethod();
            if (method.getPersonCommunicationMethodType().getCode()
                    .equals(PersonCommunicationMethodType.TYPE_PHONE_CALL)) {
                displayInfo.setTitle("Phone Call");
            } else if (method.getPersonCommunicationMethodType().getCode()
                    .equals(PersonCommunicationMethodType.TYPE_EMAIL)) {
                displayInfo.setTitle("Email");
                displayInfo.setBackgroundColor(emailBackgroundColor);
            } else {
                displayInfo.setTitle("Communication");
                displayInfo.setBackgroundColor(phoneBackgroundColor);
            }
            Person toPerson = personCommunication.getPerson();
            Person fromPerson = personCommunication.getPerson();
            if (toPerson.getId().equals(person.getId())) {
                displayInfo.setSubTitle("From: " + fromPerson.getName());
            } else {
                displayInfo.setSubTitle("To: " + toPerson.getName());
            }

        } else if (personExpirable instanceof Interview) {
            Interview interview = (Interview) personExpirable;
            displayInfo.setTitle("Interview");
            displayInfo.setSubTitle(interview.getPerson().getName());
            displayInfo.setContent("<font>" + interview.getEncounterStatus() + "</font>" + "<br><font>" + "Status: "
                    + interview.getStatusType().getName() + "</font>");
            displayInfo.setBackgroundColor(interviewBackgroundColor);
        } else if (personExpirable instanceof UserEvaluation) {
            UserEvaluation evaluation = (UserEvaluation) personExpirable;
            displayInfo.setTitle("Evaluation");
            displayInfo.setSubTitle(evaluation.getPerson().getName());
            displayInfo.setContent("<font>" + evaluation.getEncounterStatus() + "</font>" + "<br><font>" + "Type: "
                    + evaluation.getTypeDescription() + "</font>");
            displayInfo.setBackgroundColor(evaluationBackgroundColor);
        } else {
            displayInfo.setTitle("Encounter");
        }
    }

    /**
     * 
     * @param table
     * @param caption
     * @param id
     */
    private void addValueRow(final Table table, final String caption, final String value) {
        Row row = table.addRow();
        Cell captionCell = row.addCell();
        captionCell.setWidth(0);
        Font captionFont = new Font();
        captionFont.setClass("subFont");
        captionFont.addElement(caption);
        captionCell.addElement(captionFont);

        Cell valueCell = row.addCell();

        Div valueDiv = new Div();
        valueCell.addElement(valueDiv);

        Font valueFont = new Font();
        valueFont.setClass("subFont");
        valueFont.addElement(value);
        valueDiv.setStyle("position:relative; " + "top:0px; " + "left:0px; " + "width:100%; " + "height:100%;"
                + "background-color:#bbccdd;" + "border: solid 1px #440000;" + "text-align:left;" + "padding:2px;");
        valueDiv.addElement(valueFont);
    }

}
